package com.boot.controller;

import com.boot.enums.ResultEnum;
import com.boot.utils.Accest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.UUID;

import static org.springframework.util.StreamUtils.BUFFER_SIZE;

@Slf4j
@Controller
public class FileController {

    
    @Value("${sys.basePath}")
    private String basePath;
    @Value("${sys.imgPath}")
    private String imgPath;

    /**
     * 实现文件上传
     */
    @RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
    @ResponseBody
    public String upload(@RequestParam("file")MultipartFile file) {
        Accest.isTrue(file.isEmpty(),"文件不能为空");
        String fileName = file.getOriginalFilename();//获取文件名
        String path = basePath ;   //自定义文件存放位置
        String suffix = fileName.substring(fileName.lastIndexOf("."));//获取文件后缀名
        String newName = UUID.randomUUID().toString()+suffix;
        File dest = new File(path + newName);
        if (!dest.exists()) { //判断文件目录是否存在
            dest.mkdirs();    //创建目录
        }
        try {
            file.transferTo(dest); //保存文件
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imgPath+newName;
    }


    /**
     * 使用plupload上传文件
     * @param file		文件对象
     * @param name		文件名称
     * @param chunk		数据块序号
     * @param chunks	数据块总数
     * @return
     */
    @ResponseBody
    @RequestMapping(value="plupload",method=RequestMethod.POST)
    public String plupload(@RequestParam MultipartFile file, HttpServletRequest request, HttpSession session) {
        try {
            String name = request.getParameter("name");
            Integer chunk = 0, chunks = 0;
            if(null != request.getParameter("chunk") && !request.getParameter("chunk").equals("")){
                chunk = Integer.valueOf(request.getParameter("chunk"));
            }
            if(null != request.getParameter("chunks") && !request.getParameter("chunks").equals("")){
                chunks = Integer.valueOf(request.getParameter("chunks"));
            }
            log.info("chunk:[" + chunk + "] chunks:[" + chunks + "]");
            //检查文件目录，不存在则创建
            String relativePath = "/plupload/files/";
            String realPath = session.getServletContext().getRealPath("");
            File folder = new File(realPath + relativePath);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            //目标文件 
            File destFile = new File(folder, name);
            //文件已存在删除旧文件（上传了同名的文件） 
            if (chunk == 0 && destFile.exists()) {
                destFile.delete();
                destFile = new File(folder, name);
            }
            //合成文件
            appendFile(file.getInputStream(), destFile);
            if (chunk == chunks - 1) {
                log.info("上传完成");
            }else {
                log.info("还剩["+(chunks-1-chunk)+"]个块文件");
            }

        } catch (IOException e) {
            log.error(e.getMessage());
        }

        return "OK";
    }

    private void appendFile(InputStream in, File destFile) {
        OutputStream out = null;
        try {
            // plupload 配置了chunk的时候新上传的文件append到文件末尾
            if (destFile.exists()) {
                out = new BufferedOutputStream(new FileOutputStream(destFile, true), BUFFER_SIZE);
            } else {
                out = new BufferedOutputStream(new FileOutputStream(destFile),BUFFER_SIZE);
            }
            in = new BufferedInputStream(in, BUFFER_SIZE);

            int len = 0;
            byte[] buffer = new byte[BUFFER_SIZE];
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            try {
                if (null != in) {
                    in.close();
                }
                if(null != out){
                    out.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
    }
}
